#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDataStream>
#include <QIODevice>
#include <QDebug>
#include "modbuscrc.h"
#include <QMessageBox>
#include <QRegExp>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->slaveData->setEnabled(false);
    m_serialportInfo = new QLabel();

    ui->statusBar->addPermanentWidget(m_serialportInfo);

    QRegExp regExp("[a-fA-F0-9]+$");
    ui->slaveData->setValidator(new QRegExpValidator(regExp, this));


    connect(&m_serialport,SIGNAL(readyRead()),this,SLOT(readyRead()));
    m_revTimer.setSingleShot(true);
    connect(&m_revTimer,SIGNAL(timeout()),this,SLOT(receiveTimeout()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pbCreate_clicked()
{
    quint8 uid = ui->slaveUnitID->value();
    quint8 func = ui->slaveFunc->currentText().toInt();
    quint16 idx = ui->slaveIndex->value();
    quint16 value = ui->slaveValue->value();
   QByteArray strhex = ui->slaveData->text().toLatin1();
   QByteArray data = QByteArray::fromHex(strhex);

    QByteArray pdu;
    QDataStream out(&pdu,QIODevice::WriteOnly);

    if(ui->master->isChecked())
    {
        out << func;
        out << idx;
        out << value;
        if(func > 6)
        {
            if(strhex.size() != value)
            {
                QMessageBox::warning(this,tr("note"),tr("Data length is incorrect.\nPlease set the data!"));
                return;
            }
            pdu.append(quint8(data.size()));
            pdu.append(data);
        }

    }
    else
    {

        pdu.append(func);
        pdu.append(quint8(value));
        pdu.append(data);
    }

    QByteArray adu = modbuscrc::create(uid,pdu);

    if(m_AduList.contains(adu))
    {
        ui->statusBar->showMessage("ADU : [ " + adu.toHex().toUpper() + " ] already exists",2000);
        return;
    }
    m_AduList.append(adu);
    ui->sendList->addItem(adu.toHex().toUpper());



}


void MainWindow::on_slaveFunc_currentIndexChanged(int index)
{
    if(ui->master->isChecked())
    {
        ui->slaveIndex->setVisible(true);
        ui->lbslaveIndex->setVisible(true);
        if(index>4)
        {
            ui->slaveData->setEnabled(true);

        }else
        {
            ui->slaveData->setEnabled(false);
        }
    }
    else
    {
        if(index > 2)
        {
             ui->slaveData->setEnabled(false);
             ui->slaveIndex->setVisible(true);
             ui->lbslaveIndex->setVisible(true);
        }
        else
        {
            ui->slaveData->setEnabled(true);
            ui->slaveIndex->setVisible(false);
            ui->lbslaveIndex->setVisible(false);
        }
    }

}

void MainWindow::on_clear_clicked()
{
    ui->sendList->clear();
    m_AduList.clear();
}


void MainWindow::on_sendList_itemDoubleClicked(QListWidgetItem *item)
{
    qDebug()  << item->text();
    ui->sendBuffer->setText(item->text());
}

void MainWindow::on_send_clicked()
{
    if(ui->sendBuffer->text().isEmpty())
    {
        ui->statusBar->showMessage(tr("No data to send!"),2000);
        return;
    }
    QByteArray strhex = ui->sendBuffer->text().toLatin1();
    QByteArray adu = QByteArray::fromHex(strhex);
    if(!m_serialport.isOpen())
    {
        QMessageBox::warning(this,tr("serialport"),tr("serial port disconnect"));
        return;
    }
    m_serialport.write(adu);
    ui->statusBar->showMessage(tr("Send ADU:") + adu.toHex().data(),2000);
}

void MainWindow::on_actionSetting_triggered()
{
    Setting *set = new Setting(&m_set);
    set->show();
}

void MainWindow::on_actionConnect_triggered()
{
    if(m_set.portName.isEmpty())
    {
        on_actionSetting_triggered();
        ui->actionConnect->setChecked(false);
        return;
    }
    if(m_serialport.isOpen())
    {
        ui->actionConnect->setChecked(true);
        return;
    }

    m_serialport.setPortName(m_set.portName);
    m_serialport.setBaudRate(m_set.bardrate);
    m_serialport.setParity(m_set.parity);
    m_serialport.setDataBits(QSerialPort::Data8);
    m_serialport.setStopBits(QSerialPort::OneStop);
    m_serialport.setFlowControl(QSerialPort::NoFlowControl);
    if(!m_serialport.open(QSerialPort::ReadWrite))
    {
        QMessageBox::warning(this,tr("连接"),m_serialport.errorString());
        ui->actionConnect->setChecked(false);
        return;
    }

    ui->actionConnect->setChecked(true);
    ui->actionDisconnect->setChecked(false);
    m_serialportInfo->setText(tr("%1-%2-%3")
                              .arg(m_serialport.portName())
                              .arg(m_serialport.baudRate())
                              .arg(m_serialport.parity()));

}

void MainWindow::on_actionDisconnect_triggered()
{
    m_serialport.close();
    ui->actionConnect->setChecked(false);
    ui->actionDisconnect->setChecked(true);
    m_serialportInfo->clear();
}

void MainWindow::on_slaveData_textChanged(const QString &arg1)
{

    qDebug() << arg1;
    int pos = ui->slaveValue->value();
    QString str = arg1;
    str =str.remove(QRegExp("\\s"));
    int idx = ui->slaveFunc->currentText().toInt();
    if((idx == 15)||(idx == 1)||(idx == 2))
    {
        str.truncate(pos*2);
    }
    else if((idx == 16)||(idx == 3))
    {
        str.truncate(pos*4);
    }
    else
    {
        return;
    }
    ui->slaveData->setText(str.toUpper());
}


void MainWindow::on_master_clicked()
{
    on_slaveFunc_currentIndexChanged(ui->slaveFunc->currentIndex());
}

void MainWindow::on_slave_clicked()
{
    on_slaveFunc_currentIndexChanged(ui->slaveFunc->currentIndex());
}


void MainWindow::readyRead()
{
    m_receiveBuffer.append(m_serialport.read(m_serialport.bytesAvailable()));
    m_revTimer.start(ui->receiveTimeout->value());
}
void MainWindow::receiveTimeout()
{
    ui->receiveList->addItem(m_receiveBuffer.toHex());
    m_receiveBuffer.clear();
}

void MainWindow::on_receiveListClear_clicked()
{
    ui->receiveList->clear();
}
